#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <memory>
#include "InetAddr.hpp"
//#include "Reactor.hpp"
#include "Epoller.hpp"

class Reactor;
//class Connection;

//using func_t = std::function<void(std::shared_ptr<Connection>)>;

// 普通的fd，listensockfd
// 让对fd的处理方式采用同一种方法
// 描述一个连接
class Connection 
{
public:
    Connection()
        : _sockfd(-1), _events(0)
    {}

    // void InitCB(func_t recver, func_t sender, func_t exceptor)
    // {
    //     _recver = recver;
    //     _sender = sender;
    //     _exceptor = exceptor;
    // }

    void SetSockfd(int sockfd)
    {
        _sockfd = sockfd;
    }
    
    void SetAddr(const InetAddr& peer_addr)
    {
        _peer_addr = peer_addr;
    }

    void SetPeerAddr(const InetAddr& peer_addr)
    {
        _peer_addr = peer_addr;
    }

    int Sockfd() { return _sockfd; }
    void SetEvents(uint32_t events) { _events = events; }
    uint32_t GetEvents() const { return _events; }
    void SetOwner(Reactor* owner) { _owner = owner; }
    Reactor* GetOwner()  { return _owner; }

    void Append(const std::string &in)
    {
        _inbuffer += in;
    }

    void AppendToOut(const std::string &out)
    {
        _outbuffer += out;
    }

    void DisCardOutString(int n)
    {
        _outbuffer.erase(0, n);
    }

    bool IsOutBufferEmpty() const { return _outbuffer.empty(); }

    std::string &InBuffer() { return _inbuffer; }

    std::string &OutBuffer() { return _outbuffer; }

    void Close()
    {
        if(_sockfd > 0)
            close(_sockfd);
    }

    virtual void Recver() = 0;
    virtual void Sender() = 0;
    virtual void Exceptor() = 0;

    ~Connection(){}
protected:
    int _sockfd;
    std::string _inbuffer;
    std::string _outbuffer;
    InetAddr _peer_addr;  // 对应哪一个客户端

    // 回调方法
    // func_t _recver;
    // func_t _sender;
    // func_t _exceptor;

    // 添加一个指针
    Reactor* _owner;

    // 关心的事件
    uint32_t _events;
};

// class Factory
// {
// public:
//     static std::shared_ptr<Connection> BuildConnection(int fd, uint32_t events, func_t r, func_t s, func_t e)
//     {
//         auto conn = std::make_shared<Connection>(fd);
//         conn->SetEvents(events);
//         conn->InitCB(r, s, e);
//         return conn;
//     }
// };